package com.gdepri.cabelwellserver.server;

import com.gdepri.cabelwellserver.entity.CabelMessage;
import com.gdepri.cabelwellserver.entity.CableMessageSegment;
import com.gdepri.cabelwellserver.handler.BusinessHandler;
import com.gdepri.cabelwellserver.handler.ByteArrHandler;
import com.gdepri.cabelwellserver.handler.ByteMsgDecoder;
import com.gdepri.cabelwellserver.handler.ByteMsgEncoder;

import com.gdepri.cabelwellserver.tools.ByteFun;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

public class ServerReaderThread extends  Thread{
    private Logger logger = LoggerFactory.getLogger(ServerReaderThread.class);
    ByteFun byteFun = new ByteFun();
    ArrayList<Byte> byteArr= new ArrayList<>();
    private Socket socket;
//    CableMessageSegmentService service;
//    public ServerReaderThread(Socket socket,CableMessageSegmentService service){
//        this.socket = socket;
////        this.service = service;
//    }
    public ServerReaderThread(Socket socket){
        this.socket = socket;
//        this.service = service;
    }
    @Override
    public void run() {
        try{
            //发送一个对时报文
            byte[] timeSyncBytes = getTimeSyncBytes();
            logger.info("发送对时报文："+Arrays.toString(timeSyncBytes));
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(timeSyncBytes);
            outputStream.flush();

            byte[] ipInfoBytes = getIpInfoBytes();
            logger.info("发送IP地址报文："+Arrays.toString(ipInfoBytes));
            outputStream.write(ipInfoBytes);
            outputStream.flush();


            //读取设备上送数据
            ByteArrHandler byteArrHandler = new ByteArrHandler();
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);

            while(true){
                try{
                      byte b = dis.readByte();
                      logger.info(Integer.toHexString(b)+" "+b);
                      byteArr.add(b);
                      if((byte)0x9E == b) {
                          logger.info("(byte)0x9E == b");
                            //启动一次解析
                          ArrayList<byte[]> msgs = byteArrHandler.findMsgs(byteArr);
                          //parseMsg(msgs,service);
                          parseMsg(msgs);
                      }

                }catch(Exception e){
                    e.printStackTrace();
                    logger.info("设备挂掉了:"+socket.getRemoteSocketAddress());
                    is.close();
                    socket.close();
                    break;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }


//    public void parseMsg( ArrayList<byte[]> msgs,CableMessageSegmentService service){
        public void parseMsg( ArrayList<byte[]> msgs){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sdf.format(new Date());

        logger.info("@@@需要遍历："+msgs.size());
        int counter = 0;
        for(byte[] msg:msgs){
            logger.info("---------bytes---------------");
            String s = Arrays.toString(msg);
            logger.info(s);

            logger.info("XXXcounter："+counter++);
            try{
                logger.info("消息长度为："+msg.length);
                //插入到日志
                CableMessageSegment cableMessageSegment = new CableMessageSegment();
                cableMessageSegment.setDatastr(new String(msg,"ISO-8859-1"));
                cableMessageSegment.setInsertTime(format);


                byte[] testBytes = msg;

                ByteMsgDecoder decoder = new ByteMsgDecoder();
                ByteMsgEncoder encoder = new ByteMsgEncoder();

                logger.info("@@@decoder进行解码！");
                CabelMessage message = decoder.decode(testBytes);
                logger.info("==============中间的对象==============");
                logger.info(String.valueOf(message));

                logger.info("准备数据库对象");
                cableMessageSegment.setDirection(message.getDirection());
                cableMessageSegment.setType(message.getFuncCode()+"");
                //logger.info("打印service对象:"+service);
                logger.info("打印数据库对象");
                logger.info(cableMessageSegment.toString());
                //service.upsert(cableMessageSegment);

                logger.info("============================");
                logger.info("----------解码之后的报文----------");
                logger.info("----------解码之后的报文----------");
                byte[] encode = encoder.encode(message);
                logger.info("@@@encoder进行编码！");
                logger.info("----------编码之后的报文----------");

                logger.info("解码之前的,解码之后的");
                logger.info("testBytes大小:"+testBytes.length);
                logger.info("decoder大小:"+encode.length);
                for(int i=0;i<testBytes.length;i++){
                    logger.info(byteFun.pasreByte2Binary(testBytes[i]));
                    logger.info("  ");
                    logger.info(byteFun.pasreByte2Binary(encode[i]));
                    logger.info(" ");
                }
            }catch (Exception e){
                logger.info(e.getMessage());
                logger.info("该报文有错误！");
            }

        }
    }

    public byte[] getTimeSyncBytes(){
        BusinessHandler businessHandler = new BusinessHandler();
        ByteMsgEncoder encoder = new ByteMsgEncoder();
        CabelMessage timesyncMessage = businessHandler.timesync();
        byte[] timesync = encoder.encode(timesyncMessage);
        return timesync;
    }
    public byte[] getIpInfoBytes(){
        BusinessHandler businessHandler = new BusinessHandler();
        ByteMsgEncoder encoder = new ByteMsgEncoder();
        CabelMessage ipInfo = businessHandler.ipInfo("121.36.223.253",18889);
        byte[] timesync = encoder.encode(ipInfo);
        return timesync;
    }
}
